// Copyright by Thomas Maierhofer / MSE-iT, Hauptstrasse 32, 88427 Bad Schussenried, Germany
// See licence file of project for licencing details
// Contact: thomas@maierhofer.de


#include "stdafx.h"
#include "SetupBootstrapLib.h"
#include "SetupBootstrapLibInternal.h"

BEGIN_MESSAGE_MAP(CSetupApp, CWinApp)
	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()

volatile bool CSetupApp::CancelSetup = false; 
CSetupApp * CSetupApp::SetupApp = 0;
CWizardDialog * CSetupApp::SetupDlg = 0;

CSetupApp::CSetupApp( bool (* initFkt)(void) )
{
	initializeFunction = initFkt;
	SetupApp = this;
}


void CSetupApp::AttachZipResource(int resourceID )
{
	HRSRC hrsrc = FindResource(0,MAKEINTRESOURCE(resourceID),RT_RCDATA);
	HANDLE hglob = LoadResource(0,hrsrc);
	void *zipbuf = LockResource(hglob);
	unsigned int ziplen = SizeofResource(0,hrsrc);
	zipResource = OpenZip(zipbuf, ziplen, 0);
}


bool CSetupApp::ExistsResource(CString file )
{
	ZIPENTRY ze; 
	int i; 
	ZRESULT result = FindZipItem(zipResource,file,true,&i,&ze);
	return result == ZR_OK;
}



// Take HBITMAP from embedded ZIP
HBITMAP CSetupApp::GetBitmapResource( CString file )
{
	ZIPENTRY ze; int i; FindZipItem(zipResource,file,true,&i,&ze);
	// that lets us search for an item by filename.
	// Now we unzip it to a membuffer.
	char *ibuf = new char[ze.unc_size];
	UnzipItem(zipResource,i, ibuf, ze.unc_size);

	BITMAPINFOHEADER * infoHeader = (BITMAPINFOHEADER * ) ( ibuf + sizeof(BITMAPFILEHEADER) ) ;

	BITMAPINFOHEADER &bmiHeader = *infoHeader;
	BITMAPINFO &bmInfo = *(LPBITMAPINFO)infoHeader ;

	// If bmiHeader.biClrUsed is zero we have to infer the number
	// of colors from the number of bits used to specify it.
	long nColors = bmiHeader.biClrUsed ? bmiHeader.biClrUsed :
						1 << bmiHeader.biBitCount;

	LPVOID lpDIBBits;
	if( bmInfo.bmiHeader.biBitCount > 8 )
		lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) +
			((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
	else
		lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);

	CClientDC dc(NULL);
	CBitmap * old = dc.GetCurrentBitmap();

	CPalette* pOldPalette = NULL;

	if(bmInfo.bmiHeader.biBitCount == 32 ) // Alpha Channel
	{
		// pre-multiply rgb channels with alpha channel
		for (int y=0; y<bmInfo.bmiHeader.biHeight; ++y)
		{
			BYTE *pPixel= (BYTE *) lpDIBBits + bmInfo.bmiHeader.biWidth * 4 * y;

			for (int x=0; x<bmInfo.bmiHeader.biWidth ; ++x)
			{
				pPixel[0]= pPixel[0]*pPixel[3]/255;
				pPixel[1]= pPixel[1]*pPixel[3]/255;
				pPixel[2]= pPixel[2]*pPixel[3]/255;
				pPixel+= 4;
			}
		}
	}

	

	HBITMAP hBmp = CreateDIBitmap( dc.m_hDC,		// handle to device context 
				&bmiHeader,	// pointer to bitmap size and format data 
				CBM_INIT,	// initialization flag 
				lpDIBBits,	// pointer to initialization data 
				&bmInfo,	// pointer to bitmap color-format data 
				DIB_RGB_COLORS);		// color-data usage 


	dc.SelectObject(old); 		

	delete[] ibuf;
	return hBmp;
}

HBITMAP CSetupApp::GetLocalizedBitmapResource( CString file )
{
	CString localFileName = GetLanguagePrefix() + "-" + file;
	if( ExistsResource(localFileName) )
		return GetBitmapResource(localFileName);

	CString neutralFileName = GetNeutralLanguagePrefix() + "-" + file;
	if( ExistsResource(neutralFileName) )
		return GetBitmapResource(neutralFileName);

	return 0;
}


CString CSetupApp::GetTextResource(CString file )
{
	ZIPENTRY ze; 
	int i; 
	FindZipItem(zipResource,file,true,&i,&ze);
	char *ibuf = new char[ze.unc_size+1];
	UnzipItem(zipResource,i, ibuf, ze.unc_size);
	
	ibuf[ze.unc_size] = 0;
	CString result = ibuf;
	delete[] ibuf;
	return result;
}

CString CSetupApp::GetLocalizedTextResource(CString file )
{
	CString localFileName = GetLanguagePrefix() + "-" + file;
	if( ExistsResource(localFileName) )
		return GetTextResource(localFileName);

	CString neutralFileName = GetNeutralLanguagePrefix() + "-" + file;
	if( ExistsResource(neutralFileName) )
		return GetTextResource(neutralFileName);

	return "";
}

void CSetupApp::SetLanguagePrefix(CString prefix)
{
	languagePrefix = prefix;

	CString text = GetTextResource( languagePrefix + ".txt" );
	Messages.SetSize(0);
	SplitString(text,"\n",Messages );
	ASSERT(Messages.GetCount() >= LIB_LAST );  // Be sure the messages are available.

	if( CSetupApp::SetupDlg != 0 )
		CSetupApp::SetupDlg->LocalizeControls();
}

void CSetupApp::SetNeutralLanguagePrefix(CString prefix)
{
	neutralLanguagePrefix = prefix;

	if( CSetupApp::SetupDlg != 0 )
		CSetupApp::SetupDlg->LocalizeControls();
}




BOOL CSetupApp::InitInstance()
{
	CWinApp::InitInstance();

	if( ! initializeFunction() )
		return FALSE;

	if (SetupDlg->DoModal() == ID_WIZFINISH)
	{
		// AfxMessageBox("Finished Wizard");
	}
	else
	{
		// AfxMessageBox("Cancelled Wizard");
	}


	return FALSE;
}



int CSetupApp::ExitInstance( void )
{
	if( CSetupApp::SetupDlg != 0 )
		delete CSetupApp::SetupDlg;  // must be crated with new!

	return 0;
}




// **************************** Detection ***************************
	// .NET Detection
bool CSetupApp::CheckNetfx30BuildNumber() {	CDetectFxRegistry detect(""); return detect.CheckNetfx30BuildNumber(); }
bool CSetupApp::CheckNetfx35BuildNumber() { CDetectFxRegistry detect(""); return detect.CheckNetfx35BuildNumber(); }
int CSetupApp::GetNetfx10SPLevel() { CDetectFxRegistry detect(""); return detect.GetNetfx10SPLevel(); }
int CSetupApp::GetNetfx11SPLevel() { CDetectFxRegistry detect(""); return detect.GetNetfx11SPLevel(); }
int CSetupApp::GetNetfx20SPLevel() { CDetectFxRegistry detect(""); return detect.GetNetfx20SPLevel(); }
int CSetupApp::GetNetfx30SPLevel() { CDetectFxRegistry detect(""); return detect.GetNetfx30SPLevel(); }
int CSetupApp::GetNetfx35SPLevel() { CDetectFxRegistry detect(""); return detect.GetNetfx35SPLevel(); }
bool CSetupApp::IsNetfx10Installed() { CDetectFxRegistry detect(""); return detect.IsNetfx10Installed(); }
bool CSetupApp::IsNetfx11Installed() { CDetectFxRegistry detect(""); return detect.IsNetfx11Installed(); }
bool CSetupApp::IsNetfx20Installed() { CDetectFxRegistry detect(""); return detect.IsNetfx20Installed(); }
bool CSetupApp::IsNetfx30Installed() { CDetectFxRegistry detect(""); return detect.IsNetfx30Installed(); }

// SQl Detection
bool CSetupApp::IsSQLExpress2005SP2Installed() {return ::IsSQLExpress2005SP2Installed(); }